using System.Collections.Generic;

using Microsoft.SharePoint;

using RealDolmen.SharePoint.Helpers;

namespace RealDolmen.SharePoint.ListFeatures
{
    public class ListFeatureItemEventReceiver : SPItemEventReceiver
    {
        private SPSite tempSite;
        private SPWeb tempWeb;

        public void SetWithoutEventFiring(SPListItem item, string key, object value)
        {
            DisableEventFiring();
            SPListItemHelper.Set(
                item,
                key,
                value);
            EnableEventFiring();
        }

        private List<ListFeature> ComputeFeatures(SPItemEventProperties properties)
        {
            ListFeature original = ListFeatureTracker.Instantiate(new ListFeatureCompiledReceiverData(properties.ReceiverData).TrackerData).OpenListFeature(out tempWeb, out tempSite);

            return ListFeature.GetActiveListFeatures(original.ParentList, original.Definition);
        }

        private void CloseFeatureResources()
        {
            SPHelper.TryDisposeWeb(tempWeb);
            SPHelper.TryDisposeSite(tempSite);
        }
        #region ItemAdd
        public override void ItemAdded(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAdded(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemAdding(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAdding(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemAdd

        #region ItemAttachment
        public override void ItemAttachmentAdded(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAttachmentAdded(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemAttachmentAdding(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAttachmentAdding(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemAttachment

        #region ItemAttachmentDelete
        public override void ItemAttachmentDeleted(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAttachmentDeleted(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemAttachmentDeleting(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemAttachmentDeleting(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemAttachmentDelete

        #region ItemCheckIn
        public override void ItemCheckedIn(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemCheckedIn(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemCheckingIn(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemCheckingIn(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemCheckIn

        #region ItemCheckOut
        public override void ItemCheckedOut(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemCheckedOut(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemCheckingOut(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemCheckingOut(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemCheckOut

        #region ItemDelete
        public override void ItemDeleted(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemDeleted(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemDeleting(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemDeleting(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemDelete

        #region ItemFileConvert
        public override void ItemFileConverted(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemFileConverted(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemFileConvert

        #region ItemFileMove
        public override void ItemFileMoved(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemFileMoved(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemFileMoving(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemFileMoving(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemFileMove

        #region ItemUncheck
        public override void ItemUncheckedOut(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemUncheckedOut(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemUncheckingOut(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemUncheckingOut(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemUncheck

        #region ItemUpdate
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemUpdated(properties, feature);
            }
            CloseFeatureResources();
        }
        public override void ItemUpdating(SPItemEventProperties properties)
        {
            List<ListFeature> features = ComputeFeatures(properties);

            foreach (ListFeature feature in features)
            {
                feature.Register(this);
                ItemUpdating(properties, feature);
            }
            CloseFeatureResources();
        } 
        #endregion // ItemUpdate

        public virtual void ItemAdded(SPItemEventProperties properties, ListFeature listFeature){}
        public virtual void ItemAdding(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemAttachmentAdded(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemAttachmentAdding(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemAttachmentDeleted(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemAttachmentDeleting(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemCheckedIn(SPItemEventProperties properties, ListFeature listFeature){}
        public virtual void ItemCheckedOut(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemCheckingIn(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemCheckingOut(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemDeleted(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemDeleting(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemFileConverted(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemFileMoved(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemFileMoving(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemUncheckedOut(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemUncheckingOut(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemUpdated(SPItemEventProperties properties, ListFeature listFeature) { }
        public virtual void ItemUpdating(SPItemEventProperties properties, ListFeature listFeature) { }

    }
}